package com.jm.product.controller;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.java.framework.common.pagination.SearchBean;
import com.java.framework.common.pagination.SearchBean.Operator;
import com.java.framework.common.utils.Reflections;
import com.jm.product.controller.core.BaseController;
import com.jm.product.entity.Brand;
import com.jm.product.entity.Goods;
import com.jm.product.entity.GoodsCat;
import com.jm.product.entity.GoodsPhoto;
import com.jm.product.entity.GoodsSpec;
import com.jm.product.entity.GoodsType;
import com.jm.product.entity.Product;
import com.jm.product.entity.SpecValues;
import com.jm.product.entity.Specification;
import com.jm.product.entity.dto.Attribute;
import com.jm.product.entity.dto.GoodsSpecJson;
import com.jm.product.entity.dto.ParamGroup;
import com.jm.product.service.GoodsCatService;
import com.jm.product.service.GoodsPhotoService;
import com.jm.product.service.GoodsTypeService;
import com.jm.product.utils.UploadFileUtils;

/**
 * 商品管理Controller
 * @author sunshine
 * @version 2017-07-04
 */
@Controller
@RequestMapping(value = "product/goods")
public class GoodsController extends BaseController<Goods,Integer> {

	@Value("${goods.photo.tiny.width}")
	private Integer tiny_pic_width ;
	@Value("${goods.photo.tiny.height}")
	private Integer tiny_pic_height ;
	@Value("${goods.photo.thumbnail.width}")
	private Integer thumbnail_pic_width ;
	@Value("${goods.photo.thumbnail.height}")
	private Integer thumbnail_pic_height ;
	@Value("${goods.photo.small.width}")
	private Integer small_pic_width ;
	@Value("${goods.photo.small.height}")
	private Integer small_pic_height ;
	@Value("${goods.photo.big.width}")
	private Integer big_pic_width ;
	@Value("${goods.photo.big.height}")
	private Integer big_pic_height ;
	
	@Autowired
	private GoodsCatService goodsCatService;
	@Resource
	private GoodsTypeService goodsTypeService;
	@Resource
	private GoodsPhotoService goodsPhotoService;
	
	protected String listPage() {

		return "product/goodsList";
	}
	
	@RequestMapping("selectCat")
	public String selectCat() {
		return "product/selectCat";
	}

	public String form(Goods goods, Model model) {
		if (null != goods && null != goods.getId()){
			model.addAttribute("goods", this.data);
			model.addAttribute("goodsCat", this.data.getGoodsCat());
			
			//属性
			String props = this.data.getProps();
			if(StringUtils.isNotBlank(props)){
				List<Attribute> attrs = JSON.parseArray(props, Attribute.class) ;
				model.addAttribute("props", attrs);
			}
			//参数
			String params = this.data.getParams() ;
			if(StringUtils.isNotBlank(params)){
				List<ParamGroup> pgs = JSON.parseArray(params, ParamGroup.class) ;
				model.addAttribute("params", pgs);
			}
		} else {
			if(null != goods && null != goods.getGoodsCat() && null != goods.getGoodsCat().getId()){
				GoodsCat cat = goodsCatService.getById(goods.getGoodsCat().getId()) ;
				model.addAttribute("goodsCat", cat);
				
				GoodsType type = cat.getGoodsType();
				if("1".equals(type.getHaveProp())){
					String props = type.getProps();
					List<Attribute> attrs = JSON.parseArray(props, Attribute.class) ;
					model.addAttribute("props", attrs);
				}
				if("1".equals(type.getHaveParm())){
					String params = type.getParams();
					List<ParamGroup> pgs = JSON.parseArray(params, ParamGroup.class) ;
					model.addAttribute("params", pgs);
				}
			}
		}
		return "product/goodsForm";
	}
	
	@RequestMapping(value = "delete")
	@ResponseBody
	public Map<String, Object> delete(@RequestParam Integer id, RedirectAttributes redirectAttributes) {
		Map<String, Object> returnMap = Maps.newHashMap() ;
		try {
			this.service.removeById(id);
			returnMap.put(SUCCESS, true);
			returnMap.put(MESSAGE, "删除成功") ;
			
			// 删除存储的图片
			List<SearchBean> sbs = Lists.newArrayList(new SearchBean("goods.id", id, Operator.EQ));
			List<GoodsPhoto> gps = this.goodsPhotoService.list(sbs, null, 0, Integer.MAX_VALUE);
			for (GoodsPhoto gp : gps) {
				String file = gp.getOriginal() ;
				if(file.startsWith("http")) continue;
				String filePath = getUploadRootPath() + file ;
				UploadFileUtils.delete(filePath);
			}
		} catch (Exception e) {
			returnMap.put(SUCCESS, false);
			returnMap.put(MESSAGE, "删除失败") ;
			e.printStackTrace();
		}
		return returnMap;
	}
	
	public String savePage() {

		return "redirect:/product/goods/?repage";
	}
	
	@Override
	public String save(Goods goods, Model model, RedirectAttributes redirectAttributes, HttpServletRequest request) {
		// TODO Auto-generated method stub
		if (!beanValidator(model, data)){
			return form(data, model);
		}
		this.processGoods(goods, request);
		this.processImage(goods, request);
		this.processSpec(goods, request);
		List<Product> nonSaveProducts = goods.getProductList() ;
		this.proessProps(goods, request);
		this.proessParams(goods, request);
		Goods saveGoods = service.save(data); // 保存商品
		this.processGoodsSpec(saveGoods, nonSaveProducts);
		addMessage(redirectAttributes, "保存成功");
		return savePage();
	}
	
	/**
	 * 更新goods里面的specs
	 * @param goods 保存后的商品
	 */
	private void processGoodsSpec(Goods goods, List<Product> nonSaveProducts) {
		if(goods == null) return ;
		List<Product> productList = goods.getProductList() ;
		List<GoodsSpecJson> jsonList = Lists.newArrayList();
		int i = 0;
		for (Product product : productList) {
			GoodsSpecJson json = new GoodsSpecJson();
			BeanUtils.copyProperties(product, json);
			json.setGoods_id(goods.getId());
			json.setProduct_id(product.getId());
			json.setSpecList(nonSaveProducts.get(i).getSpecList());
			jsonList.add(json);
			i++;
		}
		String specs = JSON.toJSONString(jsonList) ;
		goods.setSpecs(specs);
		service.saveOrUpdate(goods); // 更新specs
	}
	
	/**
	 * 处理商品属性
	 * @param goods
	 * @param request
	 */
	private void processGoods(Goods goods, HttpServletRequest request) {
		String brandId = request.getParameter("brandId") ;
		if(StringUtils.isNotBlank(brandId)){
			Brand brand = new Brand() ;
			brand.setId(Integer.parseInt(brandId));
			goods.setBrand(brand);
		}
		GoodsCat cat = goodsCatService.getById(goods.getGoodsCat().getId()) ;
		goods.setGoodsType(cat.getGoodsType());
		goods.setDisabled("0");
		goods.setCreateTime(new Date());
	}
	
	/**
	 * 处理商品图片
	 * @param request
	 */
	private void processImage(Goods goods, HttpServletRequest request){
		String[] goodsPhotos = request.getParameterValues("goodsPhotos");
		String[] goodsPhotoIds = request.getParameterValues("goodsPhotoIds");
		if(goodsPhotos != null){
			goods.getGoodsPhotoList().clear();
			int i = 0;
			for (String photo : goodsPhotos) {
				Integer photoId = StringUtils.isBlank(goodsPhotoIds[i]) ? null : Integer.valueOf(goodsPhotoIds[i]);
				GoodsPhoto gp = new GoodsPhoto() ;
				gp.setId(photoId);
				gp.setOriginal(photo);
				gp.setGoods(goods);
				goods.getGoodsPhotoList().add(gp);
				i++;
			}
		}
	}
	
	/**
	 * 删除商品图片
	 * @param goods
	 * @param request
	 */
	@RequestMapping("deletePhoto")
	@ResponseBody
	public Map<String,Object> deleteImage(@RequestParam(required=false) Integer photoId, @RequestParam String file, HttpServletRequest request){
		Map<String,Object> map = Maps.newHashMap();
		try {
			if(photoId != null){
				goodsPhotoService.removeById(photoId);
			}
			map.put(SUCCESS, true);
			map.put(MESSAGE, "删除成功");
			if(file.startsWith("http")) return map;
			String filePath = getUploadRootPath() + file ;
			UploadFileUtils.delete(filePath);
		} catch (Exception e) {
			map.put(SUCCESS, false);
			map.put(MESSAGE, "删除失败");
			e.printStackTrace();
		}
		return map;
	}
	
	/**
	 * 获取有效商品数量
	 * @param sns
	 * @return
	 */
	private int getSnsSize(String[] sns) {
	    int i = 0;
	    for (String sn : sns) {
	      if (StringUtils.isNotBlank(sn)) {
	        i++;
	      }
	    }
	    return i;
	}

	/**
	 * 根据规格生成Product
	 * @param goods
	 * @param request
	 */
	private void processSpec(Goods goods, HttpServletRequest request) {
	    String haveSpec = request.getParameter("haveSpec");
	    if ("1".equals(haveSpec)) { //开启了规格
	    	String[] goodsSpecIds = request.getParameterValues("goods_spec_ids"); //GoodSpec关系id
	    	String[] specidsAr = request.getParameterValues("specids"); //规格id
	    	String[] specvidsAr = request.getParameterValues("specvids"); //规格值id
	      
	    	String[] productids = request.getParameterValues("productids"); //货品id
	    	String[] sns = request.getParameterValues("sns"); //货品编号
	    	String[] prices = request.getParameterValues("prices"); //货品价格
	    	String[] costs = request.getParameterValues("costs"); //货品成本
	    	String[] weights = request.getParameterValues("weights"); //货品重量
	      
	    	int i = 0;
	    	int snIndex = getSnsSize(sns);
	    	//clear写不写好像对更新都无影响
	    	goods.getProductList().clear();
	    	goods.getGoodsSpecMap().clear();
	    	for (String sn : sns) {
	    		Integer productId = StringUtils.isBlank(productids[i]) ? null : Integer.valueOf(productids[i]);
	    		if (StringUtils.isBlank(sn)) {
	    			sn = goods.getSn() + "-" + (snIndex + 1);
	    			snIndex++;
	    		}
	        
	    		Product product = new Product();
	    		product.setId(productId);
	    		product.setGoods(goods);
	    		product.setName(goods.getName());
	    		product.setSn(sn);
	        
	    		List<SpecValues> valueList = Lists.newArrayList();
	    		int j = 0;
	    		String[] specids = specidsAr[i].split(",");
	    		String[] specvids = specvidsAr[i].split(",");
	    		for (String specid : specids) {
	    			SpecValues specvalue = new SpecValues();
	    			specvalue.setId(Integer.valueOf(specvids[j].trim()));
	    			Specification spec = new Specification();
	    			spec.setId(Integer.valueOf(specid.trim()));
	    			specvalue.setSpecification(spec);
	    			valueList.add(specvalue);
	          
	    			//保存GoodsSpec	    			
	    			Integer goodsSpecId = StringUtils.isBlank(goodsSpecIds[(specids.length * i)+j]) ? null : Integer.valueOf(goodsSpecIds[(specids.length * i)+j]);
	    			GoodsSpec goodsSpec = new GoodsSpec() ;
	    			goodsSpec.setId(goodsSpecId);
	    			goodsSpec.setSpecification(spec);
	    			goodsSpec.setSpecValues(specvalue);
	    			goodsSpec.setProduct(product);
	    			goodsSpec.setGoods(goods);
	    			goods.getGoodsSpecMap().add(goodsSpec);
	          
	    			j++;
	    		}
	        
	    		String[] specvalues = request.getParameterValues("specvalue_" + i);
	    		product.setSpecs(StringUtils.strip(Arrays.toString(specvalues), "[]"));
	    		product.setPrice(StringUtils.isBlank(prices[i]) ? 0.0d :Double.valueOf(prices[i]));
	    		if (!"yes".equals(request.getParameter("isedit"))) {
	    			product.setStore(0);
	    		}
	    		product.setCost(StringUtils.isBlank(costs[i]) ? 0.0d : Double.valueOf(costs[i]));
	    		product.setWeight(StringUtils.isBlank(weights[i]) ? 0.0d : Double.valueOf(weights[i]));
		        /*
		        String[] lvPriceStr = request.getParameterValues("lvPrice_" + i);
		        
		        String[] lvidStr = request.getParameterValues("lvid_" + i);
		        if ((lvidStr != null) && (lvidStr.length > 0))
		        {
		          List<GoodsLvPrice> goodsLvPrices = createGoodsLvPrices(lvPriceStr, lvidStr, goodsId.intValue());
		          product.setGoodsLvPrices(goodsLvPrices);
		        }
		        */
	    		product.setSpecList(valueList);
	    		goods.getProductList().add(product);
	    		i++;
	    	}
//	      	this.productManager.add(productList);
	    } else { //未开启规格
	    		List<Product> products = goods.getProductList() ;
	    		Product product ;
	    		if(products != null && !products.isEmpty()){
	    			product = products.get(0) ;
	    		} else {
	    			product = new Product();
	    		}
	    		product.setGoods(goods);
	    		product.setCost(goods.getCost());
	    		product.setPrice(goods.getPrice());
	    		product.setSn(goods.getSn());
	    		product.setWeight(goods.getWeight());
	    		product.setName(goods.getName());
	    		/*
	      		String[] lvPriceStr = request.getParameterValues("lvPrice");
	      		String[] lvidStr = request.getParameterValues("lvid");
	      		if ((lvidStr != null) && (lvidStr.length > 0)) {
	        		List<GoodsLvPrice> goodsLvPrices = createGoodsLvPrices(lvPriceStr, lvidStr, goodsId.intValue());
	        		product.setGoodsLvPrices(goodsLvPrices);
	      		}
	    		 */
	    		goods.getProductList().clear();
	    		goods.getProductList().add(product);
	    	}
	  }
	
	/**
	 * 处理商品属性
	 * @param goods
	 * @param request
	 */
	private void proessProps(Goods goods, HttpServletRequest request) {
		String[] propnames = request.getParameterValues("propnames");
		String[] propvalues = request.getParameterValues("propvalues");
		if(propnames != null && propnames.length > 0){
			GoodsCat cat = goodsCatService.getById(goods.getGoodsCat().getId()) ;
			String oprops = cat.getGoodsType().getProps();
			List<Attribute> attrs = JSON.parseArray(oprops, Attribute.class) ;
			for (int i = 0; i < propnames.length; i++) {
				for (Attribute attribute : attrs) {
					if(attribute.getName().equals(propnames[i])){
						attribute.setValue(propvalues[i]);
					}
				}
			}
			String props = JSON.toJSONString(attrs, SerializerFeature.WriteMapNullValue,
					SerializerFeature.WriteNullListAsEmpty,
	        		SerializerFeature.WriteNullStringAsEmpty);
			
			goods.setProps(props);
		}
		//用反射设置属性字段值
		if ((propvalues != null) && (propvalues.length > 0)) {
		      int length = propvalues.length;
		      length = length > 20 ? 20 : length;
		      for (int i = 0; i < length; i++) {
		        String value = propvalues[i];
		        Reflections.invokeSetter(goods, "p" + (i + 1), value);
		      }
		}
	}
	
	/**
	 * 处理商品参数
	 * @param goods
	 * @param request
	 */
	private void proessParams(Goods goods, HttpServletRequest request) {
		String[] paramnums = request.getParameterValues("paramnums");
	    String[] groupnames = request.getParameterValues("groupnames");
	    String[] paramnames = request.getParameterValues("paramnames");
	    String[] paramvalues = request.getParameterValues("paramvalues");
	    
	    List<ParamGroup> pgs = goodsTypeService.toParamList(paramnums, groupnames, paramnames, paramvalues);
	    String params = JSON.toJSONString(pgs, SerializerFeature.WriteMapNullValue,
				SerializerFeature.WriteNullListAsEmpty,
        		SerializerFeature.WriteNullStringAsEmpty);
	    
	    goods.setParams(params);
	}
	
	@RequestMapping("checkIsInUse")
	@ResponseBody
	public Map<String, Object> checkGoods(@RequestParam Integer goodsid) {
		Map<String, Object> map = Maps.newHashMap() ;
		log.debug("goodsid : "+goodsid);
		boolean isUse = false ; //TODO: 需要实现
		if (isUse){
			map.put(SUCCESS, true) ;
		} else {
			map.put(SUCCESS, false);
		}
		return map ;
	}
	
	public static void main(String[] args) {
		String[] str = {"a","1"};
		System.out.println(StringUtils.strip(Arrays.toString(str), "[]"));
	}
}
